#!/usr/bin/perl
package TEdit::MediaFile;

use strict;
use warnings qw( all );
use TEdit::MediaFile::FLAC;
use TEdit::MediaFile::MP3;
use File::stat;
use File::Basename;
use Cwd;

our $debug = 0;

sub new {
	my $class = shift;
	my $args = shift;
	my $self = {};
	$self->{filename} = Cwd::abs_path($args->{filename}) || undef;
	$self->{_error} = undef;
	if($class eq 'TEdit::MediaFile') {
		# if we are a mediafile, we need to create
		# the correct type of subobject

		if ($self->{filename} =~ /\.flac$/i) {
			$self = TEdit::MediaFile::FLAC->new($args);
		} elsif ($self->{filename} =~  /\.mp3$/i) {
			$self = TEdit::MediaFile::MP3->new($args);
		} else {
			return undef;
		}
	} else {
		# we are inherited by a subclass
		bless($self,$class);
	}

	$self->init();
	return $self;
}

sub init { die("i exist to be overriden!"); }
sub _native_read { die("i exist to be overriden!"); }
sub _native_write { die("i exist to be overriden!"); }
sub _mapping { die("i exist to be overriden!"); }

sub _init {
	my $self = shift;
	$self->{stat} = File::stat::stat($self->{filename}) 
		or return($self->error("can't stat"));
}

sub filesize { $_[0]->{stat}->size; }
sub codec { $_[0]->{codec}; }

sub error {
	my $self = shift;
	if (@_) {
		$self->{_error} = shift;
	}
	return unless defined($self->{_error}) && $self->{_error};
	return($self->{_error});
}

sub write_tag {
        my $self = shift;
        my $tagname = shift;
        my $value = shift;

	# don't bother writing tag if we are writing an empty string
	# over a nonexistant tag
	return if( ($value eq '') && (! defined($self->read_tag($tagname)) ) );

	# don't bother writing the same tag value that already exists
	# FIXME how do we make this not warn for comparing $value to undef if
	# the tag doesn't previously exist?  wrap with { } and do 'no warnings'?
	return if( $value eq $self->read_tag($tagname) );

	$self->_native_write($self->tag2native($tagname),$value);
}

sub read_tag {
	my $self = shift;
	my $tagname = shift;
	$self->_native_read($self->tag2native($tagname));
}

sub list_all_tags {
	my $self = shift;
	die "unimpl";
}

sub tag2native {
	my $self = shift;
	my $map = $self->_mapping();
	return($map->{shift()});
}

sub remove_tag {
	my $self = shift;
	my $tagname = shift;
	$self->_native_remove($self->tag2native($tagname));
}

sub displayname {
	my $self = shift;
	return(File::Basename::basename($self->{filename}));
}

sub DESTROY {
	my $self = shift;
	$self = undef;
}

1;

__END__
